/**
 * 
 */
package core.simple;
//import java.util.Iterator;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
//import java.util.Collection;
import java.util.Set;
import java.util.HashSet;

import core.Problem;
import core.Result;
/**
 * @author AmmyLee
 *
 */
public final class SPEA2Environment extends SimpleEnvironment {

	int licznik = 0;

	List<Indyvidual> list;
	



	public SPEA2Environment(Problem problem,double mutationParameter,double mutationProbability,double cross){
		super(problem,mutationParameter,mutationProbability,cross);
	}


	

	@Override
	public void step() {
	//	Iterator<Indyvidual> it1, it2;
		Indyvidual i1,i2;
		int i,max;
//		System.out.println("Next step "+ licznik++);
		p0.countFitness(p_0, problem);

		
		

		list = new ArrayList<Indyvidual>(p0.population);
		list.addAll(p_0.population);
		Collections.sort(list);

		i = 0;
		max = list.size();
		p_0.reset();

		while ((i<max) && ((i1=list.get(i))!=null)&&((i<this.sizeOfArchieve)||i1.fitness < 1.0)){
			p_0.add(i1.genotype,i1.fitness,i1.results);
			//System.out.print(i1.fitness+" ");
			i++;
		}
		
		if (p_0.getSize()> this.sizeOfArchieve){
			//za duzo - obcinamy

			p_0.countDistances(problem);

			while (p_0.getSize() > this.sizeOfArchieve){
				//System.out.println(p_0.getSize()+" to "+this.sizeOfArchieve);
				p_0.population = p_0.truncate();
			}
		}
		
		p0.reset();
		while (p0.getSize()<this.sizeOfPopulation){
			i1 = p_0.tournamentSelection();
			i2 = p_0.tournamentSelection();


			double [][] children;
			children = this.crossOver(i1.genotype, i2.genotype);
			
			
			children[0] = this.mutate(children[0]);		
			children[1] = this.mutate(children[1]);

			
			p0.addGenotype(children[0]).results =problem.calculate(children[0]);
			p0.addGenotype(children[1]).results = problem.calculate(children[1]);
		}
		
		
	}
	
	public Set<Result> getResults(boolean nonDominated) throws Exception {
		double gen [];
		Set<Result> set = new HashSet<Result>();
		if (nonDominated){
			
			List<Indyvidual> pop = p_0.population;
			int i = 0;
			
			while (i<pop.size()){
				set.add(new Result(gen = pop.get(i).genotype, problem.calculate(gen)));
				i++;
			}
			return set;
			
		}
		else {
			
			int i = 0;
			while (i<list.size()){
				set.add(new Result (gen = list.get(i).genotype,problem.calculate(gen)));
				i++;
			}
			return set;
		}
	}
	public void resetResults(){
		//dummy
	}
	

}
